#include "StdAfx.h"
#include ".\serializestream.h"
#include "PoolMgr.h"

namespace Lumin {
namespace Win32 {

class StreamBuffer
{
};

void *CSerializeStream::operator new(size_t objectSize)
{
	return CPoolMgr<CSerializeStream>::GetInstance()->Allocate(objectSize);
}

void CSerializeStream::operator delete(void *pObject, size_t /* bufferSize*/)
{
	CPoolMgr<CSerializeStream>::GetInstance()->Free(pObject);
}

CSerializeStream::CSerializeStream(void):m_buffer(NULL),m_nSize(0),m_ref(0)
{
	//m_buffer = new char[CServer::StreamSize()];
	m_buffer = (char*)CPoolMgr<StreamBuffer>::GetInstance()->Allocate(CServer::StreamSize());
}

CSerializeStream::~CSerializeStream(void)
{
	//delete []m_buffer;
	CPoolMgr<StreamBuffer>::GetInstance()->Free(m_buffer);
	m_buffer = NULL;
}

ISerializeStream* CSerializeStream::Split(size_t length)
{
	assert(length <= m_nSize);
	ISerializeStream *pStream = new CSerializeStream();
	pStream->AddRef();
	pStream->SetData(m_buffer,length);
	m_nSize -= length;
	memmove(m_buffer,m_buffer+length,m_nSize);
	return pStream;
}

void CSerializeStream::AddRef()
{
	InterlockedIncrement(&m_ref);
}

void CSerializeStream::Release()
{
	if(InterlockedDecrement(&m_ref) == 0){
		delete this;
	}
}

bool CSerializeStream::PushData(char* data,int size)
{
	if(m_nSize + size > CServer::StreamSize())
		return false;
	memcpy(m_buffer + m_nSize,data,size);
	m_nSize += size;
	return true;
}

bool CSerializeStream::PopData(int size)
{
	if(size > m_nSize)
		return false;
	memmove(m_buffer,m_buffer+size,m_nSize - size);
	m_nSize -= size;
	return true;
}

bool CSerializeStream::SetData(char* data,int size)
{
	if(size <= CServer::StreamSize())
	{
		memcpy(m_buffer,data,size);
		m_nSize = size;
		return true;
	}
	return false;
}

}
}